package com.xrui.hbase;

import com.xrui.hbase.exception.DataRequestException;
import com.xrui.hbase.schema.TableLayout;

/**
 * This class validates a {@link DataRequest} against the layout
 * of a HBase table to make sure it contains all of the columns requested.
 * <p>
 * <p>Application authors cannot instantiate this class directly. Instead they
 * should use the factory method {@link #validatorForLayout(TableLayout)}
 * to create a validator. They can then use its {@link #validate(DataRequest)}
 * method to validate requests.</p>
 */
public final class DataRequestValidator {
    /**
     * The TableLayout to validate against.
     */
    private final TableLayout mTableLayout;

    /**
     * Construct a validator for a layout.
     *
     * @param tableLayout The table layout to validate against.
     */
    private DataRequestValidator(TableLayout tableLayout) {
        mTableLayout = tableLayout;
    }

    /**
     * Creates a validator for a table layout.
     *
     * @param tableLayout The table layout that requests will be validated against. Cannot be null.
     * @return A validator for the table layout.
     */
    public static DataRequestValidator validatorForLayout(TableLayout tableLayout) {
        if (null == tableLayout) {
            throw new IllegalArgumentException("Cannot create a validator for a null table layout.");
        }
        return new DataRequestValidator(tableLayout);
    }

    /**
     * Validates a data request against this validator's table layout.
     *
     * @param dataRequest The DataRequest to validate.
     * @throws DataRequestException If the data request is invalid.
     */
    public void validate(DataRequest dataRequest) {
        for (DataRequest.Column column : dataRequest.getColumns()) {
            final String qualifier = column.getQualifier();
            final TableLayout.ColumnLayout fLayout =
                mTableLayout.getColumnMap().get(ColumnName.create(column.getFamily(), column.getQualifier()).getName());

            if (null == fLayout) {
                if (null == mTableLayout.getColumnMap().get(column.getFamily())) {
                    throw new DataRequestException(String.format("Table '%s' has no column named '%s'.",
                        mTableLayout.getName(), column.getName()));
                }
            }
        }
    }
}
